#include "executor.h"
#include <QFile>
#include <QNetworkReply>
#include <QNetworkRequest>


Executor::Executor(DownloadTableModel * model):
    QObject(model), model(model)
{

}

void Executor::submitTask(int id, const QString &fileName, const QString &URL, int priority)
{
    QNetworkRequest request;
    request.setUrl(QUrl(URL));

    switch(priority){
    case 0: request.setPriority(QNetworkRequest::LowPriority); break;
    case 1: request.setPriority(QNetworkRequest::NormalPriority); break;
    case 2: request.setPriority(QNetworkRequest::HighPriority); break;
    }

    QFile * file = new QFile(fileName);
    if (!file->open(QIODevice::WriteOnly)) {
        return;
    }

    QNetworkReply* reply = manager.get(request);

    new ResponseHandler(reply, file, this, id);
    idToReply.insert(id,reply);
}


void Executor::cancelTask(int id)
{
    if(idToReply.contains(id)) {
        QNetworkReply * reply = idToReply[id];
        idToReply.remove(id);
        reply->abort();
    }
}

ResponseHandler::ResponseHandler(QNetworkReply *reply, QFile* out, Executor * executor, int id):
    reply(reply), out(out), executor(executor), id(id)
{
    connect(reply, SIGNAL(readyRead()), this, SLOT(newData()));
    connect(reply, SIGNAL(finished()), this, SLOT(done()));
    connect(reply, SIGNAL(downloadProgress(qint64,qint64)), this, SLOT(progress(qint64,qint64)));
    connect(this, SIGNAL(modify(int,int,QVariant)), executor->model, SLOT(modify(int,int,QVariant)));
}

void ResponseHandler::newData()
{
    out->write(reply->readAll());
}

void ResponseHandler::done()
{
    executor->idToReply.remove(id);
    if(reply->error()) {
        out->close();
        out->remove();
    }else {
        out->close();
    }
    executor->model->submitAll();
    reply->deleteLater();
    out->deleteLater();
    deleteLater();
}

void ResponseHandler::progress(qint64 read, qint64 all)
{
    emit modify(id, 4, QVariant((int)(1000. * read / all)));
}


